/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.figures;

import static java.lang.Math.max;

import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;

/**
 * @author Andreas Limyr
 * @author frankd@ifi.uio.no
 */
public class InteractionUseFigure extends AnchoringFigure {

    private static final int DEFAULT_HEIGHT = 50;
    private static final int DEFAULT_WIDTH = 200;
    private static final int MIN_WIDTH = 125;
    private static final int MIN_HEIGHT = DEFAULT_HEIGHT;

    private Label ref;
    private Label text;

    public InteractionUseFigure() {
        setLayoutManager(new XYLayout());
        setBorder(new FragmentBorder());
        setOpaque(true);

        ref = new Label("ref");
        text = new Label();
        add(ref);
        add(text);
    }

    @Override
    public Rectangle getPreferredBounds(Rectangle suggestedBounds) {
        int width = selectPreferred(MIN_WIDTH, DEFAULT_WIDTH, suggestedBounds.width);
        int height = selectPreferred(MIN_HEIGHT, DEFAULT_HEIGHT, suggestedBounds.height);
        return new Rectangle(suggestedBounds.x, suggestedBounds.y, width, height);
    }

    private int selectPreferred(int min, int defaultvalue, int suggested) {
        return suggested == 0 ? defaultvalue : max(min, suggested);
    }

    @Override
    // TODO Remove - this should be handled by layout handler
    public Dimension getPreferredSize(int w, int h) {
        Dimension prefSize = super.getPreferredSize(w, h);
        Dimension defaultSize = new Dimension(200, 100);
        prefSize.union(defaultSize);
        return prefSize;
    }

    @Override
    protected void paintFigure(Graphics graphics) {
        super.paintFigure(graphics);
        ref.setForegroundColor(this.getFontColor());
        ref.setFont(this.getFont());
        ((FragmentBorder) getBorder()).setBackgroundColor(this.getBackgroundColor());
        ((FragmentBorder) getBorder()).setColor(this.getBorderColor());
        ((FragmentBorder) getBorder()).paintLabelBackground(this, graphics);
    }

    @Override
    public void validate() {
        if (isValid())
            return;
        super.validate();

        Rectangle tr = ref.getTextBounds();
        ref.setSize(tr.width, tr.height);

        final Rectangle r = getBounds();
        tr = text.getTextBounds();
        text.setLocation(new Point((r.width - tr.width) / 2, (r.height - tr.height) / 2));
        text.setSize(tr.width, tr.height);
    }

    // TODO Pull up to superclass
    @Override
    protected boolean useLocalCoordinates() {
        return true;
    }

    // Called by the FragmentBorder to paint a frame label
    // border of the correct size
    public Rectangle getLocalTextBounds() {
        Dimension extent = FigureUtilities.getTextExtents(ref.getText(), ref.getFont());
        return new Rectangle(ref.getLocation(), extent);
    }

    // --- ILabeledFigure ---

    public Rectangle getLabelBounds() {
        Rectangle rect = text.getClientArea().getCopy();
        text.translateToAbsolute(rect);
        return rect;
    }

    public void setLabel(String labelText) {
        text.setText(labelText);
        repaint();
    }

    // --- Anchor contribution ---

    private AnchorPolicy anchorPolicy;

    public AnchorPolicy getAnchorPolicy() {
        if (anchorPolicy == null)
            anchorPolicy = new InteractionUseAnchorPolicy();
        return anchorPolicy;
    }

    public Rectangle getAnchorContributionBounds(IFigure figure) {
        if (figure instanceof InteractionUseFigure) {
            int start = ((FragmentBorder) getBorder()).getLabelHeight(this);
            return new Rectangle(0, start, getSize().width, getSize().height - start - 3);
        } else {
            Rectangle ref = figure.getBounds();
            return getBounds().getTranslated(-ref.x, -ref.y).resize(0, Grid.RESERVE);
        }
    }

    public int[] contributeAnchors(IFigure figure, int y) {
        if (figure instanceof InteractionUseFigure)
            return new int[] {
                    0, getSize().width - 1
            };
        else
            return AnchorContributor.NO_CONTRIBUTIONS;
    }
}
